//! 服务相关的协议 (Traits)
//! 
//! 对应 `ai-server` 的 `services/context_manager.py` 和 `services/contribution_keyword_manager.py` 中的 Protocol 定义。

use std::any::Any;
use std::collections::HashMap;
use std::sync::Arc;

use crate::core::manifest::{ContributeDefinition, ContributionPointDefinition};

// 定义清理函数的类型
pub type Disposer = Box<dyn FnOnce() + Send + Sync>;

/// 扩展系统的基础上下文对象 Trait
/// 对应 `ai-server` 的 `IExpansionBaseContext`
pub trait IExpansionBaseContext {
    fn register_contribution_keyword(
        &self,
        name: &str,
        impl_bean: Arc<dyn IContributionKeyword>,
    );
    fn get_contribution_keyword_impl(&self, name: &str) -> Option<Arc<dyn IContributionKeyword>>;
    fn get_extension(&self, name: &str) -> Option<Arc<dyn Any + Send + Sync>>;
    fn add_disposer(&self, disposer: Disposer);
    fn add_contribution_points(
        &self,
        contribution_points: HashMap<String, Vec<ContributionPointDefinition>>,
    );
    fn remove_contribution_points(&self, keyword: &str, name: &str);
    fn add_contributes(&self, contributes: HashMap<String, Vec<ContributeDefinition>>);
    fn remove_contributes(&self, keyword: &str, name: &str);
}

/// 请求贡献上下文 Trait
/// 对应 `ai-server` 的 `IRequestContributionContext`
pub trait IRequestContributionContext {
    fn contributor(&self) -> &str;
    fn dependencies(&self) -> Vec<String>;
}

/// 贡献关键字初始化选项
pub struct ContributionKeywordInitOptions {
    // pub devtools: Option<Arc<...>>, // 暂不实现
    // pub assertion_options: Option<Arc<...>>, // 暂不实现
}

/// 贡献关键字实现必须遵守的 Trait
/// 对应 `ai-server` 的 `IContributionKeywordImpl`
pub trait IContributionKeyword: Send + Sync {
    fn init(&self, options: ContributionKeywordInitOptions);
    fn request_contribution(
        &self,
        ctx: Arc<dyn IRequestContributionContext>,
        definitions: &[ContributeDefinition],
    );
    fn request_revoke_contribution(
        &self,
        ctx: Arc<dyn IRequestContributionContext>,
        definitions: &[ContributeDefinition],
    );
    fn request_contribution_point(
        &self,
        ctx: Arc<dyn IRequestContributionContext>,
        definitions: &[ContributionPointDefinition],
    );
    fn request_revoke_contribution_point(
        &self,
        ctx: Arc<dyn IRequestContributionContext>,
        definitions: &[ContributionPointDefinition],
    );
    fn get_context(&self, contributor: &str) -> Option<Arc<dyn Any + Send + Sync>>;
    fn destructor(&self);
}
